#雅座部署工具工具类，与部署工具相关操作都几种再次
class DeployToolUtil
  cattr_accessor :env_production, :env_huidu, :env_pre, :env_jicheng, :env_test, :env_host, :apps_of_huidu
  @@env_production = '生产环境'
  @@env_huidu = '灰度环境'
  @@env_pre = '预发环境192.168.33.11'
  @@env_test = '测试环境192.168.49.61'

  @@env_host = {
      @@env_test => ['192.168.49.61', 22, 'root', 'yE6S9NS$cfi*36^s'],
      @@env_pre => ['192.168.33.11', 22, 'root', 'LjGCvAD%4&EblZJD'],
      @@env_huidu => ['192.168.192.200', 22, 'root', 'f+Au!&)Ot^MN3.D!'],
      @@env_production => ['192.168.196.4', 22, 'root', '%4E4$WhUys*aV#Mh']

  }
  @@apps_of_huidu = []

  def DeployToolUtil.get_deploy_host_by_env(env)
    return @@env_host[env]
  end

  def DeployToolUtil.get_app_list_from_cap(env)
    command = 'find /deploy/*/config/deploy.rb|sed "s/\/deploy\///"|sed "s/\/.*//"'
    #获取编译打包机器信息
    deploy_host, port, user, password = DeployToolUtil.get_deploy_host_by_env(env)
    app_names_all = []
    begin
      Timeout.timeout(10) do
        Net::SSH.start(deploy_host, user, :password => password, :port => port) do |ssh|
          ssh.exec!(command) do |ch, stream, data|
            if stream == :stdout
              data.force_encoding 'utf-8'
              # p data
              # p data.split("\n")
              app_names_all = data.split("\n")
            else
              DeployLogger.logger.error data
            end
          end
        end
      end
    rescue e
      DeployLogger.logger.error "更新app列表失败: #{e.message}"
      DeployLogger.logger.error e.backtrace.join("\n")
    end
    return app_names_all
  end

  #独立线程调用部署命令并处理结果
  def DeployToolUtil.start_capistrano_task(deployHistory)
    #校验并发部署
    task_running = DeployHistory.all.where("start_time >= current_date and status = 0 and app_name=? and env=? and id !=?",
                                           deployHistory.app_name, deployHistory.env, deployHistory.id)
    if task_running.size > 0
      DeployLogger.logger.error(task_running.first)
      DeployLogger.logger.error("并发操作拦截 capistrano:#{deployHistory.deploy_type} [#{deployHistory.app_name} #{deployHistory.env}] ")
      deployHistory.log = "并发操作拦截 capistrano:#{deployHistory.deploy_type} [#{deployHistory.app_name} #{deployHistory.env}] "
      deployHistory.status = 9
      deployHistory.save
      return
    end


    cap_command = deployHistory.deploy_type
    command = "source /etc/profile; source ~/.bash_profile; cd /deploy/#{deployHistory.app_name};"
    if (cap_command == 'deploy')
      if(deployHistory.svn_git == 'svn')
        command += "cap deploy -S s_svn_url=#{deployHistory.svn_address} -S s_svn_revision=#{deployHistory.svn_revision} -S deploy_app=#{deployHistory.app_name};"
      else
        command += "cap deploy -S s_git_url=#{deployHistory.git_address} -S s_git_revision=#{deployHistory.git_revision} -S deploy_app=#{deployHistory.app_name};"
      end
      #command += "cap deploy -S s_svn_url=#{deployHistory.svn_address} -S s_svn_revision=#{deployHistory.svn_revision} -S deploy_app=#{deployHistory.app_name};"
    elsif (cap_command == 'rollback')
      command += "cap deploy:rollback;"
    elsif (cap_command == 'restart')
      command += "cap status:restart;"
    elsif (cap_command == 'start')
      command += "cap status:start;"
    elsif (cap_command == 'stop')
      command += "cap status:stop;"
    elsif (cap_command == 'status')
      command += "cap status;"
    elsif (cap_command == 'view_version')
      command += "cap version_number;"
    end

    #获取编译打包机器信息
    deploy_host, port, user, password = DeployToolUtil.get_deploy_host_by_env(deployHistory.env)
    #独立线程调用部署命令并处理结果
    Thread.new {
      sleep 1
      #capistrano部署
      DeployLogger.logger.info "任务启动 capistrano:#{cap_command} [#{deployHistory.app_name} #{deployHistory.id} #{deployHistory.env}]"
      DeployLogger.logger.info command
      begin
        Timeout.timeout(180) do
          deployHistory.log = ""
          Net::SSH.start(deploy_host, user, :password=>password, :port=>port) do |ssh|
            DeployLogger.logger.info "ssh连接成功 capistrano:#{cap_command} [#{deployHistory.app_name} #{deployHistory.id}]"
            ssh.exec!(command) do |ch, stream, data|
              data.force_encoding 'utf-8'
              DeployLogger.logger.info "[cap] #{cap_command} [#{deployHistory.app_name} #{deployHistory.id}] -- #{data}"
              deployHistory.status = 1 if data =~ /(部署|回滚|重启|启动|关闭|状态查询|版本查询)成功/
              deployHistory.log += data
              deployHistory.save
            end
          end
        end
      rescue Net::SSH::HostKeyMismatch => e
        e.remember_host!
        retry
      rescue Net::SSH::AuthenticationFailed => e
        DeployLogger.logger.error "ssh 登录失败 capistrano:#{cap_command} [#{deployHistory.app_name} #{deployHistory.id}] " + e.message
        DeployLogger.logger.error e.backtrace.join("\n")
        deployHistory.log += "ssh 登录失败 capistrano:#{cap_command} [#{deployHistory.app_name} #{deployHistory.id}] " + e.message
      rescue Timeout::Error => e
        DeployLogger.logger.error "执行超时 capistrano:#{cap_command} [#{deployHistory.app_name} #{deployHistory.id}] " + e.message
        DeployLogger.logger.error e.backtrace.join("\n")
        deployHistory.log += "执行超时 capistrano:#{cap_command} [#{deployHistory.app_name} #{deployHistory.id}] " + e.message
      rescue => e
        DeployLogger.logger.error "执行失败 capistrano:#{cap_command} [#{deployHistory.app_name} #{deployHistory.id}] " + e.message
        DeployLogger.logger.error e.backtrace.join("\n")
        deployHistory.log += "执行失败 capistrano:#{cap_command} [#{deployHistory.app_name} #{deployHistory.id}] " + e.message
      ensure
        ActiveRecord::Base.connection_pool.release_connection
      end


      #更新数据库状态
      deployHistory.status = 9 if deployHistory.status != 1
      deployHistory.end_time = Time.new
      deployHistory.save

      #更新app的update_time
      app.touch if deployHistory.status == 1

      DeployLogger.logger.info "完成调用 capistrano:#{cap_command} [#{deployHistory.app_name} #{deployHistory.id}] "
    }
  end

  @@deploy_tasks = []
  #添加部署任务
  def DeployToolUtil.add_deploy_task(deployHistory)
    @@deploy_tasks.append(deployHistory)
  end

  #启动守护线程
  def DeployToolUtil.start_daemon_thread
    DeployLogger.logger.info('开始启动 DeployToolUtil.daemonThread ...')
    Thread.new {
      while(true)
        begin
          deployHistory = @@deploy_tasks.pop
          start_capistrano_task(deployHistory) if deployHistory
        rescue => e
          DeployLogger.logger.error "任务启动失败 capistrano:#{deployHistory.deploy_type} [#{deployHistory.app_name} #{deployHistory.id}] " + e.message
          DeployLogger.logger.error e.backtrace.join("\n")
          deployHistory.log = "任务启动失败 capistrano:#{deployHistory.deploy_type} [#{deployHistory.app_name} #{deployHistory.id}] " + e.message
          deployHistory.status = 9
          deployHistory.save
        ensure
          ActiveRecord::Base.connection_pool.release_connection
          sleep(1)
        end

      end
    }
  end

end
